<template>
  <div class="md-editor-container">
    <MdEditor
      ref="mdEditor"
      v-model="currentContent"
      class="full"
      :preview="preview"
      :toolbars="toolbar"
      :show-toolbar-name="true"
      :footers="[]"
      :read-only="readOnly"
      @on-upload-img="onUploadImg"
      @on-save="onSave"
      @on-change="onChange"
    />
  </div>
</template>

<script setup>
import {MdEditor} from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import oss from "@/plugins/ossUtil.js"

const props = defineProps({
  // 是否显示预览
  preview: {
    type: Boolean,
    default: true
  },
  // 是否显示工具栏名称
  showToolbarName: {
    type: Boolean,
    default: true
  },
  // 图片上传路径
  uploadPath: {
    type: String,
    default: 'article/'
  },
  // 是否只读
  readOnly: {
    type: Boolean,
    default: true
  },
  // 高度
  height: {
    type: [String, Number],
    default: 31.25
  },
  width: {
    type: [String, Number],
    default: '100%'
  },
  // 工具栏配置
  toolbarMode: {
    type: String,
    validator: (value) => ['full', 'simple', 'default'].includes(value),
    default: 'default'
  },
})
const mdEditor = useTemplateRef('mdEditor')
const currentContent = defineModel('content', {
  type: String,
  default: ''
})

const TOOLBAR_CONFIG = {
  simple: ['bold', 'underline', 'strikeThrough', '-', 'sub', 'sup', 'code', 'table', 'image', 'preview'],
  full: [
    'bold', 'underline', 'italic', '-',
    'title', 'strikeThrough', 'sub', 'sup', 'quote', 'unorderedList', 'orderedList', 'task', '-',
    'codeRow', 'code', 'link', 'image', 'table', 'mermaid', 'katex', '-',
    'revoke', 'next', 'save', '=',
    'pageFullscreen', 'fullscreen', 'preview', 'previewOnly', 'htmlPreview', 'catalog'
  ]
}

const toolbar = computed(() => {
  switch (props.toolbarMode) {
    case 'simple':
      return TOOLBAR_CONFIG.simple
    case 'full':
      return TOOLBAR_CONFIG.full
    default:
      return TOOLBAR_CONFIG.full.filter(item =>
          !['htmlPreview', 'save'].includes(item)
      )
  }
})

onMounted(() => {
  imgUrls.value = getContentImgs()
})

const imgUrls = ref([])
const onUploadImg = async (files, callback) => {
  $xl.modal.openLoading('资源上传中')
  const uploadPromises = files.map(file => oss.upload(file, props.uploadPath, true, null, false))
  const uploadRes = await Promise.all(uploadPromises)
  $xl.modal.closeLoading()
  callback(uploadRes)
}

const emit = defineEmits(['save', 'image-change'])

function onSave(content) {
  emit('save', content)
  clearImg()
  emit('image-change', getContentImgs())
}

const onChange = (content) => {
  currentContent.value = content
}

function clearImg() {
  const useImgs = getContentImgs()
  const a = new Set(useImgs)
  const b = new Set(imgUrls.value)
  // 获取已删除的图片url
  const removeImgs = Array.from(
      new Set(
          [...b].filter(x => !a.has(x))
      )
  )
  if (removeImgs.length > 0) {
    oss.deleteMulti(removeImgs)
    console.log('删除废弃资源', removeImgs)
  }
  return useImgs
}

const getContentImgs = () => {
  const regexp = /!\[.*?]\((.*?)\)/g
  let result = regexp.exec(currentContent.value)
  const useImgs = []
  while (result !== null) {
    useImgs.push(result[1])
    result = regexp.exec(currentContent.value)
  }
  return useImgs
}

const editorHeight = computed(() => typeof props.height === 'number' ? props.height + 'rem' : props.height)
const editorWidth = computed(() => typeof props.width === 'number' ? props.width + 'rem' : props.width)
const save = () => {
  mdEditor.value.triggerSave()
}
defineExpose({
  clearImg,
  save
})
</script>

<style lang="scss" scoped>
.md-editor-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: v-bind(editorHeight);
  width: v-bind(editorWidth);
}

:deep(.md-editor) {
  height: 100%;
  width: 100%;
}
</style>
